package com.instalinks.android.apps.smspostservice.tasks;

import java.net.URLDecoder;
import java.util.Hashtable;

import com.instalinks.android.apps.smspostservice.helper.AppConfig;
import com.instalinks.android.apps.smspostservice.helper.ConfigParams;
import com.instalinks.android.lib.AppHelper;
import com.instalinks.android.lib.UrlData;
import com.instalinks.android.lib.UrlResponse;
import com.instalinks.android.lib.UrlResponse.UrlResponseType;
import com.instalinks.android.lib.enums.PhoneParams;

import android.content.Context;
import android.os.AsyncTask;

public class SmsPostingTask extends AsyncTask<Void, Void, Boolean> {

	private AppConfig appCfg;
	private Context context;
	private String sender;
	private String message;

	private int iSuccessCount = 0;
	private int iInvalidCount = 0;
	private int iDroppedCount = 0;
	private int iFailedCount = 0;
	private int iAvailableFreeCount = 0;

	private final static int MAX_RETRIES = 1;

	public SmsPostingTask(Context context, String sender, String message) {
		appCfg = new AppConfig(context);
		this.context = context;
		this.sender = sender;
		this.message = message;
	}

	@Override
	protected Boolean doInBackground(Void... params) {
		return processSMS();
	}

	@Override
	protected void onPostExecute(Boolean boolValue) {
		saveTotalCounts();
	}

	private boolean processSMS() {
		if (!appCfg.checkForDemoVersion()) {
			return false;
		}

		if (!appCfg.isConnectedToNetwork() || !appCfg.isValidDataNetwork()) {
			try {
				iFailedCount++;

				sendFailAutoReply(sender);
			} catch (Exception e) {
				appCfg.alert("No/Invalid Data Network");
				return false;
			}
			return true;
		}

		return processSMS(sender, message);
	}

	private boolean processSMS(String sSender, String sText) {
		String sender = sSender.replace("+", "");

		boolean responseValue = false;

		iAvailableFreeCount--;

		boolean doProcess = false;

		if (sText.length() == 0) {
			iInvalidCount++;
		} else if (appCfg.isAlphanumericSenderFlag()
				|| AppHelper.isValidPhoneNumber(sender)
				|| (appCfg.isShortcodeSenderFlag() && AppHelper
						.isValidShortCode(sender))) {
			doProcess = true; // PROCESS ALL SMS
		} else {
			iInvalidCount++;
		}

		if (doProcess) {
			UrlResponse result = processUrlPosting(sender, sText);

			if (result.getResponseType() == UrlResponseType.success) {
				iSuccessCount++;
				responseValue = true;

				try {
					AppHelper.updateSMS(context, sSender, sText, "[POSTED]",
							appCfg.isMarkAsReadFlag());
				} catch (Exception e) {
					appCfg.alert("Error marking SMS as read " + e.getMessage());
				}

				String autoResponse = result.getMessage();

				if (appCfg.isAutoReplyFlag()
						&& AppHelper.isValidPhoneNumber(sender))
					AppHelper.sendSingleSms(context, sSender, autoResponse);

			} else if (result.getResponseType() == UrlResponseType.invalid) {
				iInvalidCount++;
			} else if (result.getResponseType() == UrlResponseType.dropped) {
				iDroppedCount++;
				sendFailAutoReply(sSender);
			} else {// if (result.getResponseType() ==
					// UrlResponseType.failed) {
				iFailedCount++;
			}
		}

		return responseValue;
	}

	private UrlResponse processUrlPosting(String sSender, String sText) {

		UrlData urlPost = new UrlData(appCfg.getDataPostUrl(), 25000);

		UrlResponse result = new UrlResponse(UrlResponseType.exception, "");

		for (int i = 0; i < MAX_RETRIES
				&& result.getResponseType() == UrlResponseType.exception; i++) {
			Hashtable<String, String> htParams = appCfg.getDataPostHashtable();

			htParams.put(ConfigParams.mode.toString(),
					ConfigParams.modes.urlpost.toString());
			htParams.put(PhoneParams.sender.toString(), sSender);
			htParams.put(PhoneParams.text.toString(), sText);

			try {
				result = urlPost.postData(htParams);
			} catch (Exception e) {
				result = new UrlResponse(UrlResponseType.exception, "");
			}

			if (result.getResponseType() == UrlResponseType.exception
					&& i == MAX_RETRIES - 1) {
				result.setResponseType(UrlResponseType.dropped);
			}
		}

		return result;
	}

	private void sendFailAutoReply(String sender) {
		try {
			boolean failAutoReply = appCfg.isAutoReplyFlag();
			String failedMsg = URLDecoder.decode(appCfg.getFailReplyMsg(),
					"UTF-8");

			if (failAutoReply)
				AppHelper.sendSingleSms(context, sender, failedMsg);
		} catch (Exception e) {
			appCfg.alert("No/Invalid Data Network");
		}
	}

	private void saveTotalCounts() {
		try {
			appCfg.setSmsSuccessCount(appCfg.getSmsSuccessCount()
					+ iSuccessCount);
		} catch (Exception e) {
		}
		try {
			appCfg.setSmsInvalidCount(appCfg.getSmsInvalidCount()
					+ iInvalidCount);
		} catch (Exception e) {
		}
		try {
			appCfg.setSmsDroppedCount(appCfg.getSmsDroppedCount()
					+ iDroppedCount);
		} catch (Exception e) {
		}

		try {
			appCfg.setSmsFailedCount(appCfg.getSmsFailedCount() + iFailedCount);
		} catch (Exception e) {
		}

		try {
			appCfg.setAvailableFreeCount(appCfg.getAvailableFreeCount()
					+ iAvailableFreeCount);
		} catch (Exception e) {
		}
	}
}
